package io.gitee.zhangbinhub.admin.oauth.controller.api

import cn.dev33.satoken.annotation.SaCheckPermission
import cn.dev33.satoken.stp.StpUtil
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.api.OauthApi
import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.oauth.entity.Role
import io.gitee.zhangbinhub.admin.oauth.po.RolePo
import io.gitee.zhangbinhub.admin.oauth.service.RoleService
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.gitee.zhangbinhub.admin.resource.server.vo.RoleVo
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.*
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.NotEmpty
import org.noear.solon.validation.annotation.NotNull
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("角色信息")
open class RoleController(
    private val logAdapter: LogAdapter,
    private val roleService: RoleService
) : BaseResourceServerController(logAdapter) {

    private val roleCodeList: MutableList<String> = mutableListOf()

    @ApiOperation("获取角色编码列表")
    @SaCheckPermission(ModuleFuncCode.roleConfig, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.roleCodes,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    fun findRoleCode(): List<String> = roleCodeList

    @Init
    fun init() {
        try {
            for (field in RoleCode::class.java.declaredFields) {
                val value = field.get(RoleCode::class.java)
                if (value is String) {
                    roleCodeList.add(value)
                }
            }
            roleCodeList.sort()
        } catch (e: Exception) {
            logAdapter.error(e.message, e)
        }
    }

    @ApiOperation("获取指定应用下可编辑的角色列表", notes = "查询指定应用下可编辑的角色列表")
    @SaCheckPermission(ModuleFuncCode.roleConfig, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.roleList + "/{appId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun getRoleList(@Path(name = "appId") appId: String): List<Role> =
        roleService.getRoleListByAppId(StpUtil.getLoginIdAsString(), appId)

    @ApiOperation("获取角色列表", notes = "查询所有角色列表")
    @SaCheckPermission(ModuleFuncCode.roleQuery, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun roleList(): List<Role> = roleService.getRoleList()

    @ApiOperation("新建角色信息", notes = "名称、编码、应用ID、级别、序号、关联用户、关联菜单、关联模块功能")
    @SaCheckPermission(ModuleFuncCode.roleAdd, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PUT],
        value = OauthApi.basePath + OauthApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun add(@Body @Validated rolePo: RolePo): Role {
        if (CommonTools.isNullStr(rolePo.appId)) {
            throw WebException("应用ID不能为空")
        }
        return roleService.doCreate(StpUtil.getLoginIdAsString(), rolePo)
    }

    @ApiOperation("删除指定的角色信息")
    @SaCheckPermission(ModuleFuncCode.roleDelete, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.DELETE],
        value = OauthApi.basePath + OauthApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun delete(
        @ApiParam("id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @Body
        idList: MutableList<String>
    ): InfoVo = roleService.doDelete(StpUtil.getLoginIdAsString(), idList).let { InfoVo(message = "删除成功") }

    @ApiOperation("更新角色信息", notes = "名称、编码、级别、序号、关联用户、关联菜单、关联模块功能")
    @SaCheckPermission(ModuleFuncCode.roleUpdate, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PATCH],
        value = OauthApi.basePath + OauthApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun update(@Body @Validated rolePo: RolePo): Role {
        if (CommonTools.isNullStr(rolePo.id)) {
            throw WebException("ID不能为空")
        }
        return roleService.doUpdate(StpUtil.getLoginIdAsString(), rolePo)
    }

    @ApiOperation("获取角色详细信息")
    @SaCheckPermission(ModuleFuncCode.roleQuery, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.roleConfig + "/{roleId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun roleInfo(@Path(name = "roleId") roleId: String): RoleVo = roleService.getRoleInfo(roleId)

}
